//
// Created by Administrator on 2021/9/28.
//

#ifndef MRENDER_MATRIX4X4_H
#define MRENDER_MATRIX4X4_H
#include <vector>
#include "Vector3.h"
#include "MatrixN.h"

class Matrix4x4 : public MatrixN{

public:
    Matrix4x4();

    /**
     * 乘法
     * @param m 矩阵
     * @return 乘法后结果
     */
    Matrix4x4 operator *(const Matrix4x4& m) const;

    /**
     * 数乘
     * @param f
     * @return
     */
    Matrix4x4 operator *(const float f) const;

    /**
     * 向量相乘
     * @param v
     * @return
     */
    Vector3 operator *(const Vector3 v);

    /**
     * 乘法
     * @param m1 矩阵1
     * @param m2 矩阵2
     * @return
     */
    static Matrix4x4 multiply(const Matrix4x4& m1, const Matrix4x4& m2);

    /**
     * 转置
     * @return
     */
    Matrix4x4 transpose();


    /**
     * 行列式
     * @return
     */
    float determinant();

    /**
     * 余子式
     * @return
     */
    Matrix4x4 cofactors();

    /**
     * 求矩阵的逆
     * @return 逆矩阵
     */
    Matrix4x4 inverse();

    /**
     * 平移变换
     * @return 变换矩阵
     */
    static Matrix4x4 translation(const Matrix4x4& m, const Vector3& v);

    /**
     * 旋转变换
     * @param rad旋转弧度
     * @return 旋转矩阵
     */
    static Matrix4x4 rotation(const Matrix4x4& m, float rad, const Vector3& v);

    /**
     * 缩放变换
     * @return 缩放矩阵
     */
    static Matrix4x4 scale(const Matrix4x4& m, const Vector3& v);

    /**
     * 正交投影
     * @param left 左
     * @param right 右
     * @param bottom 下
     * @param top 上
     * @param near 近
     * @param far 远
     * @return 投影矩阵
     */
    static Matrix4x4 orthographic(float left, float right, float bottom, float top, float near, float far);

    /**
     * 透视矩阵
     * @param radfov 视野角度
     * @param aspect 宽高比
     * @param near 近
     * @param far 远
     * @return 投影矩阵
     */
    static Matrix4x4 perspective(float radfov, float aspect, float near, float far);


    /**
     * Lookat 相机矩阵
     * @param position 位置
     * @param target 观察点
     * @param up  上方向
     * @return 矩阵
     */
    static Matrix4x4 lookAt(const Vector3& position, const Vector3& target, const Vector3& up);
};


#endif //MRENDER_MATRIX4X4_H
